package com.guardian.command.util;

import com.guardian.StartupArgument;
import com.guardian.command.Command;
import com.guardian.command.CommandLoader;
import com.guardian.command.constant.CommandConstant;
import com.guardian.communication.CommunicationClient;
import com.guardian.exception.InitializationException;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 命令工具
 * @author: huwei
 * @date: 2019/10/11 10:57
 * @version: 1.0.0
 */
public class CommandUtil {

    /**
     * 加载指定包路径下的Command对象到内存中
     * @param commandDirPackageName command对象的包名，该包名相对于com.guardian.command包名之下；示例：startup ，即加载com.guardian.command.startup包下的Command对象
     * @return Command对象的map集合，其中key为命令名称
     * @throws InitializationException 加载失败
     */
    public static Map<String ,Command> loadCommand(String commandDirPackageName) throws InitializationException {
        Map<String ,Command> map = new HashMap<>(16);
        CommandLoader commandExecutorLoader = new CommandLoader(commandDirPackageName);
        Set<Command> commandExecutorSet =  commandExecutorLoader.load();
        commandExecutorSet.forEach(x->{
            String[] commandNames = x.command();
            for (String commandName : commandNames) {
                map.put(commandName ,x);
            }
        });
        return map;
    }

    /**
     * 生成命令的help文档
     * @param commandMap 命令的map映射
     * @return
     */
    public static String helpCommand(Map<String , Command> commandMap){
        StringBuffer sb = new StringBuffer();
        Set<Command> commandExecutorSet = new HashSet<>(commandMap.size());
        commandMap.forEach((k, v)->{
            //过滤同命令执行器多个名称的情况
            if(!commandExecutorSet.contains(v)) {
                sb.append(v.commandIntro()).append(Command.LINE_BREAK);
                commandExecutorSet.add(v);
            }
        });
        return sb.toString();
    }

    /**
     * 编码执行器命令格式
     * @param args 命令参数
     * @return
     */
    public static String encodeExecutorCommand(String command ,String[] args){
        StringBuffer sb = new StringBuffer();
        sb.append(command).append(CommandConstant.EXECUTOR_COMMAND_SPILT_SYMBOL);
        if(args != null) {
            for (String arg : args) {
                sb.append(arg).append(CommandConstant.EXECUTOR_COMMAND_SPILT_SYMBOL);
            }
        }
        return sb.toString();
    }

    public static String sendMessageToMain(String command ,String[] args){
        String s = null;
        try{
            s = new CommunicationClient(){}.sendMessage("127.0.0.1" , StartupArgument.port() , CommandUtil.encodeExecutorCommand(command ,args));
        } catch (IOException e){
        }
        return s == null ?  "command execute fail" : s;
    }
}
